package com.ant.storage.config;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.ant.storage.mapper.UserInfoMapper;
import com.ant.storage.pojo.UserInfo;
import com.ant.storage.service.IDataMsgService;
import com.ant.storage.service.IUserInfoService;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import org.apache.http.HttpResponse;
import org.apache.http.HttpStatus;
import org.apache.http.client.HttpClient;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.impl.client.HttpClients;
import org.apache.http.util.EntityUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.web.servlet.HandlerInterceptor;

import javax.annotation.Resource;
import javax.servlet.ServletContext;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.PrintWriter;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashMap;
import java.util.Map;


/**
 * @author hzd
 * @version 1.0
 * @date 2022/3/16 9:15
 */
public class TokenInterceptor implements HandlerInterceptor {

    @Value("${loginUrl.url}")
    private String Url;

    @Autowired
    IUserInfoService userInfoService;

    @Resource
    UserInfoMapper infoMapper;

    @Autowired
    public ServletContext servletContext;
    @Autowired
    private IDataMsgService changeDb;

    private final static String URL_WHITELIST[] = {
            "/storageApi/login",
            "/storageApi/login/loginApplet",
            "/storageApi/login/findLogin",
            "/storageApi/login/aLineOfLogin",
//            "/storageApi/cashbook/getBalance",
            "/storageApi/login", "/storageApi/login/loginOut", "/swagger-ui.html",
            "/swagger-resources/**", "/storageApi/doc.html",
            "/swagger/**",
            "/WeChat/InvoiceInfoSave",
            "/storageApi/WeChat/Callback",
            "/storageApi/uploadFile/singleUpload",
            "/storageApi/uploadFile/singleUploads",
            "/storageApi/uploadFile/upload",
            "/storageApi/uploadFile/UploadImage",
            "/storageApi/DingDing/CallBack",
            "/storageApi/commodity/uploadCommodity",
            "/storageApi/depreciation/uploadDepreciation",
            "/captcha", "/admin/**", "/password",
            "/storageApi/Images/storage/",
            "/storageApi/planned-procurement/uploadCommodity",
            "/storageApi/planned-procurement/uploadCommoditys",
            "/storageApi/inventory/uploadInventory",
            "/storageApi/userInfo/**",
            "/storageApi/login/getText",
            "/storageApi/login/aLineOfLogin",
            "/storageApi/login/userLogin",
            "/storageApi/User/queryUserList",
            "/storageApi/supplierInformation/getSupplierInformationList",
            "/storageApi/city/queryCity",
            "/storageApi/dictionary/findDictionaryWhere",
            "/storageApi/goodsUnits/getGoodsUnitsList",
            "/storageApi/department/getDepartmentList",
            "/storageApi/User/queryUserList",
            "/storageApi/User/getDepId",
            "/storageApi/User/getUserId",
            "/storageApi/warehouse/getWarehouseList",
            "/storageApi/city/getCityList",
            "/storageApi/userInfo/getUserList",
            "/storageApi/error",
            "/storageApi/userInfo/findUsersByRoleIdsAndCityIds",
            "/storageApi/inventory/downLoadExportCensus",
            "/storageApi/bidInformation/downLoadExportCensus",
            "/storageApi/contract/downLoadExportCensus",
            "/storageApi/storage-contract/downLoadExportCensus",
            "/storageApi/houseLease/downLoadExportCensus",
            "/storageApi/contract/uploadCommodity",
            "/storageApi/image/**", "/storageApi/pic/**"};
    @Override
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
        changeDb.delDb();
        String token = request.getHeader("token");
        String url = request.getRequestURI();
        if ("OPTIONS".equals(request.getMethod())) {
            return true;
        }
        if (url.equals("/storageApi/DingDing/CallBack")) {
            return true;
        }
        if (new ArrayList<>(Arrays.asList(URL_WHITELIST)).contains(url) || url.contains(".jpg") || url.contains(".png"
        ) || url.contains(".pdf") || url.contains(".xls") || url.contains(".xlsx") || url.contains(".doc") || url.contains(".docx")) {
            return true;
        }
       UserInfo one = infoMapper.selectOne(new QueryWrapper<UserInfo>().eq("token", token));
       if(one==null){
            boolean bean = codeToken(response, token);
            if (bean) {
                   one = infoMapper.selectOne(new QueryWrapper<UserInfo>().eq("token", token));
                if (one != null) {
                    servletContext.setAttribute("userInfo", one);
                    return true;
                }
            }
        }else{
           servletContext.setAttribute("userInfo", one);
       }
        return true;
    }

   public   boolean  codeToken(HttpServletResponse response, String token) throws Exception {
        HttpClient client = HttpClients.createDefault();
        //登录接口路径
        String urls = Url + "/userSystem/user/findUserTokenByToken";
        HttpGet get = new HttpGet(urls);
        JSONObject jsonObject = null;
        try {
            get.addHeader("content-type", "application/json");
            get.addHeader("Token", token);
            HttpResponse res = client.execute(get);
            if (res.getStatusLine().getStatusCode() == HttpStatus.SC_OK) {
                String str = EntityUtils.toString(res.getEntity());
                jsonObject = JSONObject.parseObject(str);
                String code = jsonObject.get("code").toString();
                if(jsonObject.isEmpty() || !jsonObject.containsKey("data")){
                    returnJson(response, "登录超时,请重新登录");
                }
                if (("401").equals(code)) {
                    returnJson(response, "登录超时,请重新登录");
                    return false;
                } else {
                    String data = jsonObject.get("data").toString();
                    JSONObject object = JSONObject.parseObject(data);
                    String user = object.get("user").toString();
                    JSONObject object1 = JSONArray.parseObject(user);
                    String id = object1.get("id").toString();
                    UserInfo userInfo = infoMapper.selectOne(new QueryWrapper<UserInfo>().eq("token", token));
                    if (userInfo == null) {
                        infoMapper.findUpdateById(Integer.parseInt(id), token);
                    }
                    return  true;
                }
            }
        } catch (Exception e) {
            returnJson(response, "token已经过期");
            e.printStackTrace();
        }
        return  false;
    }

    /**
     * 返回格式化后的json到前端页面
     *
     * @param response
     * @param message
     * @throws Exception
     */
    private static void returnJson(HttpServletResponse response, String message) throws Exception {
        response.setContentType("application/json;charset=UTF-8");
        PrintWriter writer = response.getWriter();
        // 注意点1：这边返回配置为josn格式
        try {
           // response.reset();
            Map<String, Object> result = new HashMap<>();
            result.put("code", 403);
            result.put("message", message);
            // 注意点2，这样要用fastjson转换一下后，返回的前端才是格式化后的json格式
            writer.print(JSON.toJSONString(result));
            writer.close();
            writer.flush();
        } finally {
            if (writer != null) {
                writer.close();
                writer.flush();
            }
        }
    }

}
